package Aula12;

import java.util.ArrayList;
import java.util.Random;


public class DominoImpl implements Domino{
	
	private final int NUM_JOGADORES = 4;
	private final int PECAS_JOGADORES = 6;
	private ArrayList<ListaSimples> jogadores;
	private ListaSimples pecasSurpresa;
	private ListaSimples mesa;
	private boolean iniciado;
	
	public DominoImpl(){
		iniciado = false;
		jogadores = new ArrayList<ListaSimples>();
		for(int i = 0; i < NUM_JOGADORES; i++){
			jogadores.add(new ListaSimples());
		}
	}
	
	public void setup(){
		iniciado = true;
		mesa = new ListaSimples();
		pecasSurpresa = new ListaSimples();
		ListaSimples todasPecas = new ListaSimples();
		for(int i = 0; i <= 6; i++){
			for(int j = i; j <= 6; j++){
				todasPecas.add(new Peca(i, j));
			}
		}
		
		Random r = new Random();
		ListaSimples lista;
		Peca peca;
		int n;
		for(int i = 0; i < NUM_JOGADORES; i++){
			lista = jogadores.get(i);
			for(int j = 0; j < PECAS_JOGADORES; j++){
				n = r.nextInt(todasPecas.size());
				peca = (Peca) todasPecas.get(n);
				lista.add(peca);
				todasPecas.remove(peca);
			}
		}
		
		for(int i = 0; i < todasPecas.size(); i++){
			pecasSurpresa.add(todasPecas.get(i));
		}
		
	}
	
	/**
	 * Menor peca que um jogador tenha.
	 * @param lista - lista de pecas.
	 * @param num1 - numero da esquerda.
	 * @param num2 - numero da direita. 
	 * @return menor peca, caso nao retorna null
	 */
	
	private Peca menorPeca(ListaSimples lista, int num1, int num2){
		Peca peca;
		Peca menor = null;
		for(int i = 0; i < lista.size(); i++){
			peca = (Peca)lista.get(i);
			if(peca.containNumber(num1) || peca.containNumber(num2)){
				if(menor == null){
					menor = peca;
				}else if(peca.getValor() < menor.getValor()){
					menor = peca;
				}
			}
		}
		return menor;
	}
	
	/**
	 * Jogador com menor valor.
	 * @return jogador com menor valor
	 */
	
	private int menorJogador(){
		int menorSoma = 0, menor = 0, soma = 0;
		ListaSimples lista = jogadores.get(0); 
		for(int i = 0; i < lista.size(); i++){
			menorSoma += ((Peca) lista.get(i)).getValor();
		}
		
		for(int i = 1; i < NUM_JOGADORES; i++){
			soma = 0;
			lista = jogadores.get(i);
			
			for(int j = 0; j < lista.size(); j++){
				soma += ((Peca)lista.get(j)).getValor();
			}
			
			if(soma < menorSoma){
				menorSoma = soma;
				menor = i;
			}
		}
		return menor;
	}

	
	public Retorno jogar() {
		
		if(!iniciado){
			return null;
		}
		
		Retorno retorno = new Retorno();
		int jogador = 0, num1, num2, passou = 0;
		Peca peca = null;
		boolean axou = false;
		
		for(int i = 6; i >= 0; i--){
			peca = new Peca(i, i);
			for(int j = 0; j < NUM_JOGADORES;j++){
				if(jogadores.get(j).contains(peca)){
					jogador = j;
					axou = true;
					break;
				}
			}
			if(axou){
				break;
			}
		}
		
		mesa.add(peca);
		jogadores.get(jogador).remove(peca);
		jogador++;
		
		while(true){
			
			if(jogador == NUM_JOGADORES){
				jogador = 0;
			}
			
			
			num1 = ((Peca)mesa.getCauda()).getNum2();
			num2 = ((Peca)mesa.getCabeca()).getNum1();
			peca = menorPeca(jogadores.get(jogador), num1, num2);
			
			if(peca != null){
				
				passou = 0;
			
				if(peca.containNumber(num1)){
					if(peca.getNum1() != num1)
						peca.inverter();
					mesa.add(peca);
				}else{
					if(peca.getNum2() != num2)
						peca.inverter();
					mesa.addCabeca(peca);
				}
				jogadores.get(jogador).remove(peca);
			}else{
				passou++;
			}
			
			if(jogadores.get(jogador).size() == 0){
				retorno.numeroJogadorVencedor = jogador;
				retorno.mesa = mesa;
				iniciado = false;
				return retorno;
			}
			
			if(passou == NUM_JOGADORES){
				retorno.numeroJogadorVencedor = menorJogador();
				retorno.mesa = mesa;
				iniciado = false;
				return retorno;
			}
			jogador++;
		}
		
	}
	
}
